import './style.scss'
function notValue(v) {
  return v === undefined || v === null
}
import axios from 'axios'
import { getToken } from '@/utils/auth'
function createAxiosInstance() {
  const http = axios.create({
    // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
    withCredentials: true, // send cookies when cross-domain requests
    timeout: 180000 // request timeout
  })
  http.interceptors.request.use(cfg => {
    cfg.headers['Authorization'] = `Bearer ${getToken()}`
    return cfg
  })
  http.interceptors.response.use(resp => {
    if (![1, '1'].includes(resp.data.success)) {
      return Promise.reject(resp)
    }
    return resp
  })
  return http
}

const dictHttp = createAxiosInstance()

function getDataDict(dictTypeCode, appCode = 'slm', domainCode = 'marketing') {
  const cacheKey = `${dictTypeCode}_${domainCode}_${appCode}`
  const cacheData = sessionStorage.getItem(cacheKey)
  if (cacheData) {
    try {
      return Promise.resolve(JSON.parse(cacheData).content)
    } catch (error) {
      sessionStorage.removeItem(cacheKey)
    }
  }
  return dictHttp({
    url: `/data-dict/api/v2/dictionary/${dictTypeCode}`,
    method: 'GET',
    params: {
      appCode,
      domainCode
    }
  }).then(res => {
    const data = res.data
    try {
      data.data.sort((a, b) => {
        return b.sort - a.sort
      })
      sessionStorage.setItem(cacheKey, JSON.stringify({
        dataType: 'object',
        datetime: new Date().getTime(),
        type: 'sessionStorage',
        content: data.data
      }))
    } catch (e) {
      console.log(e)
    }
    return data.data
  })
}

const defaultProps = () => ({
  valueKey: {
    type: String,
    default: ''
  },
  labelKey: {
    type: String,
    default: ''
  },
  // 格式化显示label
  formatLabel: {
    type: Function,
    default: undefined
  },
  // 请求
  beforeRequest: {
    type: [Function],
    default: axiosConfig => axiosConfig
  },
  afterResponse: {
    type: [Function],
    default: axiosResponse => axiosResponse
  },
  // 参数构建前
  beforeParams: {
    type: Function,
    default: paramsJson => {
      return paramsJson
    }
  },
  // update:所有
  syncAll: {
    type: Boolean,
    default: false
  },
  // 参数类型
  type: {
    type: String,
    default: 'formData' // json
  },
  method: {
    type: String,
    default: 'POST'
  },
  url: {
    type: String,
    default: ''
  },
  // 标准分页参数
  pageSize: {
    type: Number,
    default: 20
  },
  filtersRaw: {
    type: Array,
    default: undefined
  },
  paramsRaw: {
    type: Object,
    default: undefined
  },
  // url查询参数
  query: {
    type: Object,
    default: undefined
  },
  // 查询key
  queryKey: {
    type: String,
    default: 'keyword'
  },
  // 操作 queryKey 位于filtersRaw时
  operator: {
    type: String,
    default: 'LIKE'
  },
  // 查询参数位置 queryKey 参数位置
  queryPosition: {
    type: String,
    default: 'query' // filtersRaw paramsRaw
  },
  queryRequired: { // query是否必传，如果为true则查询参数为空字符串也传
    type: Boolean,
    default: false
  },
  // 依赖监听
  dependOnObserve: {
    type: [String, Number, Object, Array, Boolean],
    default: ''
  },
  // 启动依赖监听
  startObserve: {
    type: Boolean,
    default: false
  },
  // el-select
  multiple: {
    type: Boolean,
    default: false
  },
  value: {
    type: [Array, String, Number],
    default: ''
  },
  label: {
    type: [Array, String, Number],
    default: ''
  },
  remote: {
    type: Boolean,
    default: true
  },
  filterable: {
    type: Boolean,
    default: true
  },
  clearable: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  collapseTags: {
    type: Boolean,
    default: true
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  // dialog
  showDialog: {
    type: Boolean,
    default: true
  },
  title: {
    type: String,
    default: ''
  },
  columns: {
    type: Array,
    default: () => []
  },
  dialogWidth: {
    type: [String, Number],
    default: '600px'
  }
})

const isType = (v, type) => Object.prototype.toString.call(v).toUpperCase() === `[object ${type}]`.toUpperCase()

export default function({ name = 'CCommonSearch', syncProps = {}, props = {}} = {}) {
  const _props = defaultProps()
  Object.entries(props).forEach(([k, v]) => {
    if (_props.hasOwnProperty(k)) {
      const vv = _props[k]
      if (!isType(v, 'object')) {
        if (!isType(vv, 'object')) {
          _props[k] = v
        } else {
          _props[k].default = v
        }
      } else {
        if (!isType(vv, 'object')) {
          _props[k] = v.default
        } else {
          _props[k].default = v.default
        }
      }
    } else {
      _props[k] = v
    }
  })
  // 处理支持.sync的props
  const keys = []
  Object.entries(syncProps).forEach(([k, v]) => {
    if (!_props.hasOwnProperty(k) && k !== _props.valueKey.default) {
      _props[k] = v
      keys.push(k)
    }
  })
  return {
    name,
    props: _props,
    data() {
      return {
        selectValue: {},
        optionsData: [],
        http: null,
        loading: false,
        error: false,
        empty: false,
        parentListener: {},
        keys,
        isFocus: false,
        // dialog
        visible: false,
        tableData: [],
        dialogValue: '',
        page: 1,
        total: 0,
        dialogLoading: false,
        selectionRows: [],
        activeTab: 'all',
        // 数据字典
        dataDicts: {},
        // 所有key
        allKeys: [],
        localSearchValue: ''
      }
    },
    computed: {
      comOptionsData() {
        return [...this.echoValue(), ...this.optionsData]
      },
      comTableData() {
        return this.tableData.filter(e => this.localSearchValue === '' || e[/^[\da-zA-Z]+$/.test(this.localSearchValue) ? this.valueKey : this.labelKey].includes(this.localSearchValue))
      }
    },
    watch: {
      value: {
        handler(v) {
          if (this.multiple) {
            if (notValue(v) || v === '' || v.length <= 0) {
              this.selectValue = []
            } else if (this.selectValue.length === 0 && v.length > 0) {
              const tmp = []
              v.forEach((e, i) => {
                const objTmp = {
                  [this.valueKey]: e,
                  [this.labelKey]: this.label[i]
                }
                this.keys.forEach(k => {
                  if (k === this.valueKey || k === this.labelKey) return // FIX: 防止被覆盖
                  objTmp[k] = this[k] instanceof Array ? this[k][i] : ''
                })
                tmp.push(objTmp)
              })
              tmp.length > 0 && this.selectValue.push(...tmp)
            }
          } else {
            if (notValue(v) || v === '') {
              this.selectValue = {}
            } else if (this.selectValue[this.valueKey] !== this.value && !notValue(this.value) && this.value !== '') {
              this.selectValue[this.valueKey] = this.value
              this.selectValue[this.labelKey] = this.label
              this.keys.forEach(k => {
                if (k === this.valueKey || k === this.labelKey) return // FIX: 防止被覆盖
                this.selectValue[k] = notValue(this[k]) ? '' : this[k]
              })
            }
          }
          if (!notValue(this.value) && this.value !== '' && this.optionsData.length <= 0) {
            this.handleRemoteMethod()
          }
        },
        immediate: true
      },
      dependOnObserve: {
        handler(v) {
          if (!this.startObserve) return
          this.optionsData = []
          this.tableData = []
          if (this.multiple) {
            this.selectValue = []
          } else {
            this.selectValue = {}
          }
          this.handleInput(this.selectValue)
        }
      },
      comOptionsData: {
        handler(v) {
          this.$emit('data-change', v)
        }
      },
      comTableData: {
        handler(v) {
          setTimeout(() => {
            (v || []).forEach(e => {
              if (this.selectionRows.some(ee => ee[this.valueKey] === e[this.valueKey])) {
                this.$refs.table.toggleRowSelection(e, true)
              }
            })
          }, 0)
        }
      }
    },
    created() {
      if (this.multiple) {
        this.selectValue = []
        if (!(this.value instanceof Array)) {
          this.$emit('input', [])
        }
        if (!(this.label instanceof Array)) {
          this.$emit('update:label', [])
        }
      }
      this.http = createAxiosInstance()
      this.setInterceptors()
      const parentListener = { ...this.$listeners }
      delete parentListener.input
      delete parentListener['visible-change']
      delete parentListener.focus
      this.parentListener = parentListener
    },
    mounted() {
      if (this.$scopedSlots.default instanceof Function) {
        this.handleRemoteMethod()
      }
    },
    methods: {
      getValue(d, key) {
        const i = d[key]
        return notValue(i) ? '' : i
      },
      echoValue() {
        if (notValue(this.value)) {
          return
        }
        const tmp = []
        if (this.multiple) {
          for (let i = 0; i < this.value.length; i++) {
            const e = this.value[i]
            const t = !this.optionsData.some(ee => ee[this.valueKey] === e && ee[this.valueKey] !== undefined)
            if (t) {
              const objTmp = {
                [this.valueKey]: e,
                [this.labelKey]: this.label[i]
              }
              this.keys.forEach(k => {
                if (k === this.valueKey || k === this.labelKey) return // FIX: 防止被覆盖
                objTmp[k] = this[k] instanceof Array ? this[k][i] : ''
              })
              tmp.push(objTmp)
            }
          }
        } else {
          if (!notValue(this.value) && this.value !== '' && !this.optionsData.some(e => e[this.valueKey] === this.value)) {
            const objTmp = {
              [this.valueKey]: this.value,
              [this.labelKey]: this.label
            }
            this.keys.forEach(k => {
              if (k === this.valueKey || k === this.labelKey) return // FIX: 防止被覆盖
              objTmp[k] = notValue(this[k]) ? '' : this[k]
            })
            tmp.push(objTmp)
          }
        }
        return tmp
      },
      syncSelectValue2Value(selectValue) {
        if (this.multiple) {
          this.$emit('input', selectValue.map(e => this.getValue(e, this.valueKey)))
          this.$emit('update:label', selectValue.map(e => this.getValue(e, this.labelKey)))
        } else {
          this.$emit('input', this.getValue(selectValue, this.valueKey))
          this.$emit('update:label', this.getValue(selectValue, this.labelKey))
        }
        this.$emit('change', selectValue)
        this.syncUpdate(selectValue)
      },
      handleInput(v) {
        this.selectValue = v
        this.syncSelectValue2Value(v)
      },
      syncUpdate(selectValue) {
        const keys = this.syncAll ? [...this.allKeys, ...this.keys] : this.keys
        if (this.multiple) {
          keys.forEach(e => {
            const k = e.replace(/(.+)_res$/, '$1')
            if (/^\$.+/.test(e)) {
              this.$emit(`update:${e}`, '$接口未返回字段$')
              return
            }
            this.$emit(`update:${e}`, selectValue.map(ee => this.getValue(ee, k)))
          })
        } else {
          keys.forEach(e => {
            const k = e.replace(/(.+)_res$/, '$1')
            if (/^\$.+/.test(e)) {
              this.$emit(`update:${e}`, '$接口未返回字段$')
              return
            }
            this.$emit(`update:${e}`, this.getValue(selectValue, k))
          })
        }
      },
      setInterceptors() {
        const beforeRequest = this.beforeRequest
        if (beforeRequest instanceof Function) {
          this.http.interceptors.request.use(beforeRequest.bind(this))
        }
        const afterResponse = this.afterResponse
        if (afterResponse instanceof Function) {
          this.http.interceptors.response.use(afterResponse.bind(this))
        }
        // 搜集所有key
        if (this.syncAll) {
          this.http.interceptors.response.use(response => {
            try {
              const res = response.data
              let data = []
              if (res.data instanceof Array) {
                data = res.data
              } else if (res.data.records instanceof Array) {
                data = res.data.records
              }
              data.forEach(e => {
                const ks = Object.keys(e)
                ks.forEach(k => {
                  k = `${k}_res`
                  if (!this.allKeys.includes(k)) {
                    this.allKeys.push(k)
                  }
                })
              })
            } catch (error) {
              console.log(error)
            }
            return response
          })
        }
      },
      getFiltersRaw(keyWord) {
        const tmp = []
        if (notValue(keyWord)) {
          keyWord = ''
        }
        const t = !this.queryRequired && keyWord === ''
        if (this.queryPosition.toUpperCase() === 'FILTERSRAW') {
          if (!t) {
            tmp.push({ id: this.queryKey, property: this.queryKey, value: keyWord, operator: this.operator })
          }
        }
        tmp.push(...(this.filtersRaw || []))
        return tmp
      },
      getParamsRaw(keyWord) {
        const tmp = {}
        if (notValue(keyWord)) {
          keyWord = ''
        }
        const t = !this.queryRequired && keyWord === ''
        if (this.queryPosition.toUpperCase() === 'PARAMSRAW') {
          if (!t) {
            tmp[this.queryKey] = keyWord
          }
        }
        return Object.assign(tmp, (this.paramsRaw || {}))
      },
      getQuery(keyWord) {
        const tmp = {}
        if (notValue(keyWord)) {
          keyWord = ''
        }
        const t = !this.queryRequired && keyWord === ''
        if (this.queryPosition.toUpperCase() === 'QUERY') {
          if (!t) {
            tmp[this.queryKey] = keyWord
          }
        }
        return Object.assign(tmp, (this.query || {}))
      },
      remoteSearch(keyWord, isDialog = false) {
        if (!this.http) {
          return Promise.reject('')
        }
        const cfg = {
          method: this.method,
          url: this.url,
          params: this.getQuery(keyWord)
        }
        if (this.method.toUpperCase() === 'GET') {
          return this.http(cfg)
        }

        let data = {
          page: isDialog ? this.page : 1,
          rows: this.pageSize,
          pageFlag: true,
          filtersRaw: this.getFiltersRaw(keyWord),
          paramsRaw: this.getParamsRaw(keyWord)
        }
        if (this.beforeParams) {
          data = this.beforeParams(data)
        }
        if (this.type.toUpperCase() === 'FORMDATA') {
          const _data = new FormData()
          Object.entries(data).forEach(([k, v]) => {
            if (isType(v, 'object') || isType(v, 'array')) {
              _data.append(k, JSON.stringify(v))
            } else {
              _data.append(k, v)
            }
          })
          data = _data
        }
        cfg.data = data
        return this.http(cfg)
      },
      handleRemoteMethod(keyWord) {
        if (this.disabled) return
        this.loading = true
        this.error = false
        this.empty = false
        return this.remoteSearch(keyWord).then(res => {
          const d = res.data.data
          if (d instanceof Array) {
            this.optionsData = d
          } else if (d.records instanceof Array) {
            this.optionsData = d.records
          }
          if (this.optionsData.length === 0) {
            this.empty = true
          }
        }).catch(() => {
          this.error = true
        }).finally(() => {
          this.loading = false
        })
      },
      handleVisibleChange(v) {
        if (this.$listeners['visible-change']) {
          this.$listeners['visible-change'].call(this)
        }
        v && this.handleRemoteMethod()
        !v && (this.isFocus = false)
      },
      handleFocus(...args) {
        this.isFocus = true
        this.$listeners.focus && this.$listeners.focus(...args)
      },
      createSselectSearch(h) {
        // search icon
        const search = h('div', {
          class: {
            search: true,
            'is-focus': this.isFocus,
            'is-disabled': this.disabled,
            'is-error': true // form-item error
          },
          on: {
            click: e => {
              e.stopPropagation()
              if (this.disabled) return
              this.visible = true
            }
          }
        }, this.showDialog ? [
          h('i', { class: 'el-icon-search' })
        ] : [])
        // loading error empty
        let tip
        if (this.empty) {
          tip = this.$scopedSlots.empty instanceof Function ? this.$scopedSlots.empty() : h('span', { class: 'common-search-empty' }, '暂无数据')
        } else if (this.loading) {
          tip = this.$scopedSlots.loading instanceof Function ? this.$scopedSlots.loading() : h('i', { class: 'el-icon-loading' })
        } else if (this.error) {
          tip = this.$scopedSlots.error instanceof Function ? this.$scopedSlots.error() : h('span', { class: 'common-search-error' }, '获取数据失败')
        }
        // el-option
        const options = this.comOptionsData.map((e, i) => {
          return h('el-option', {
            key: this.getValue(e, this.valueKey) + i.toString(),
            props: {
              value: e,
              label: this.formatLabel instanceof Function ? this.formatLabel(e) : this.getValue(e, this.labelKey)
            }
          })
        })
        tip && options.push(h('div', { class: 'loading-box', slot: 'empty' }, [tip]))
        // el-select
        const select = h('el-select', {
          class: {
            'select-i': true,
            'none-border': true
          },
          props: {
            value: this.selectValue,
            valueKey: this.valueKey,
            filterable: this.filterable,
            multiple: this.multiple,
            remote: this.remote,
            clearable: this.clearable,
            remoteMethod: this.handleRemoteMethod,
            loading: this.loading || this.error || this.empty,
            disabled: this.disabled,
            collapseTags: this.collapseTags,
            placeholder: this.placeholder,
            ...(this.$attrs || {})
          },
          on: {
            input: this.handleInput,
            focus: this.handleFocus,
            'visible-change': this.handleVisibleChange
          }
        }, options)
        // select-box
        return h('div', {
          class: {
            'select-box': true,
            'is-disabled': this.disabled
          }
        }, [select, search])
      },
      dialogHandleInput(v) {
        this.dialogValue = v
      },
      async getTableData() {
        if (this.dialogLoading || this.disabled) return Promise.reject(false)
        this.dialogLoading = true
        return this.remoteSearch(this.dialogValue, true).then(res => {
          const data = res.data
          const d = data.data
          if (d instanceof Array) {
            // this.updateTableData(d)
            this.tableData.push(...d)
            this.total = this.tableData.length
          } else if (d.records instanceof Array) {
            // this.updateTableData(d.records)
            this.tableData.push(...d.records)
            this.total = d.total
          }
          this.page++
          this.dialogLoading = false
        }).catch(() => {
          this.dialogLoading = false
        })
      },
      updateSelected() {
        if (!this.multiple) return
        const tmp = []
        this.selectValue.forEach(e => {
          const index = this.tableData.findIndex(ee => ee[this.valueKey] === e[this.valueKey])
          if (index >= 0) {
            tmp.push(this.tableData[index])
          } else {
            // this.tableData.unshift(e)
            tmp.push(e)
          }
        })
        tmp.forEach(e => {
          this.$refs.table.toggleRowSelection(e, true)
          const i = this.selectionRows.findIndex(ee => ee[this.valueKey] === e[this.valueKey])
          if (i < 0) {
            this.selectionRows.push(e)
          }
        })
      },
      updateTableData(data) {
        const rows = [...this.selectValue, ...this.selectionRows]
        this.tableData.forEach((e, i) => {
          const index = data.findIndex(ee => ee[this.valueKey] === e[this.valueKey])
          const tmp = data[index]
          if (tmp) {
            if (tmp !== e) {
              this.tableData.splice(i, 1, tmp)
              const tmp1 = rows.find(ee => ee[this.valueKey] === e[this.valueKey])
              this.$refs.table.toggleRowSelection(e, false)
              !!tmp1 && this.$refs.table.toggleRowSelection(tmp1, true)
            }
            data.splice(index, 1)
          }
        })
      },
      dialoghHandleClickSearch() {
        if (!this.remote && this.tableData.length > 0) {
          this.localSearchValue = this.dialogValue
          return
        }
        this.page = 1
        this.tableData = []
        this.total = 0
        this.getTableData()
      },
      handleOpen() {
        this.activeTab = 'all'
      },
      handleOpened() {
        if (!this.remote && this.tableData.length > 0) {
          this.localSearchValue = this.dialogValue
          return
        }
        this.page = 1
        this.tableData = []
        this.total = 0
        this.getTableData().then(() => {
          this.updateSelected()
        })
        // this.updateSelected()
      },
      handleClosed() {
        this.localSearchValue = ''
        this.dialogValue = ''
        this.activeTab = 'all'
      },
      getMore() {
        if (this.total <= this.tableData.length || (this.tableData.length > 0 && this.total <= 0)) return
        this.getTableData()
      },
      handleSelectAll(v) {
        if (v.length === 0) {
          this.comTableData.forEach(e => {
            const i = this.selectionRows.findIndex(ee => ee[this.valueKey] === e[this.valueKey])
            if (i >= 0) {
              this.selectionRows.splice(i, 1)
            }
          })
          return
        }
        v.forEach(e => {
          const existSelectionRows = this.selectionRows.some(ee => ee[this.valueKey] === e[this.valueKey])
          // const i = this.comTableData.findIndex(ee => ee[this.valueKey] === e[this.valueKey])
          if (!existSelectionRows) {
            this.selectionRows.push(e)
          }
        })
        // this.selectionRows = v
      },
      handleSelect(selection, row) {
        const i = this.selectionRows.findIndex(ee => ee[this.valueKey] === row[this.valueKey])
        const selected = selection.some(ee => ee[this.valueKey] === row[this.valueKey])
        if (i < 0 && selected) {
          this.selectionRows.push(row)
        }
        if (i >= 0 && !selected) {
          this.selectionRows.splice(i, 1)
        }
      },
      handleClickRow(row) {
        if (this.multiple) {
          const i = this.selectionRows.findIndex(ee => ee[this.valueKey] === row[this.valueKey])
          if (i >= 0) {
            this.selectionRows.splice(i, 1)
            this.$refs.table.toggleRowSelection(row, false)
          } else {
            this.selectionRows.push(row)
            this.$refs.table.toggleRowSelection(row, true)
          }
        } else {
          this.selectionRows = row
        }
      },
      handleRowDBClick(row) {
        if (!this.multiple) {
          this.selectionRows = row
          this.handleConfirm()
        }
      },
      handleClearSelected() {
        if (this.multiple) {
          this.selectionRows = []
        } else {
          this.selectionRows = {}
        }
        this.comTableData.forEach(e => {
          this.$refs.table.toggleRowSelection(e, false)
        })
      },
      handleCancelSelected(e, row) {
        e.stopPropagation()
        const i = this.selectionRows.findIndex(e => e[this.valueKey] === row[this.valueKey])
        if (i >= 0) {
          this.selectionRows.splice(i, 1)
        }
        this.$refs.table.toggleRowSelection(row, false)
      },
      handleCancel() {
        this.visible = false
        this.handleClearSelected()
      },
      handleConfirm() {
        this.handleInput(this.selectionRows)
        this.visible = false
        this.handleClearSelected()
      },
      createDialog(h) {
        // columns
        const columns = this.columns.map(e => {
          if (e.propEnum) {
            const p = e.propEnum
            const key = `${p.dictTypeCode}-${p.appCode}-${p.domainCode}`
            getDataDict(p.dictTypeCode, p.appCode, p.domainCode).then(res => {
              this.$set(this.dataDicts, key, res)
            })
            return h('el-table-column', {
              props: e,
              scopedSlots: {
                default: props => {
                  const { row } = props
                  const d = (this.dataDicts[key] || []).find(ee => ee.dictCode === row[e.prop])
                  if (d) {
                    return h('span', d.dictName)
                  }
                  return h('span', row[e.prop])
                }
              }
            })
          }
          if (e.formatData instanceof Function) {
            return h('el-table-column', {
              props: e,
              scopedSlots: {
                default: props => {
                  const { row } = props
                  return h('div', e.formatData(row))
                }
              }
            })
          }
          if (e.render) {
            return h('el-table-column', {
              props: e,
              scopedSlots: {
                default: props => {
                  const { row } = props
                  return e.render(h, row)
                }
              }
            })
          }
          return h('el-table-column', {
            props: e
          })
        })
        if (this.multiple) {
          columns.unshift(h('el-table-column', {
            props: {
              type: 'selection',
              width: 50,
              align: 'center'
            }
          }))
        }
        // table
        const table = h('el-table', {
          ref: 'table',
          props: {
            data: this.comTableData,
            height: 300,
            headerRowClassName: 'table-list-header',
            border: true,
            highlightCurrentRow: !this.multiple
          },
          on: {
            'select-all': this.handleSelectAll,
            'select': this.handleSelect,
            'row-click': this.handleClickRow,
            'row-dblclick': this.handleRowDBClick
          },
          directives: [
            {
              name: 'loading',
              value: this.dialogLoading,
              expression: 'dialogLoading',
              arg: '',
              modifiers: {}
            }
          ]
        }, columns)
        // title
        const title = h('div', {
          class: 'common-dialog-header',
          slot: 'title' }, [
          h('span', { class: 'common-dialog-title' }, this.title),
          h('div', { class: 'common-dialog-search' }, [
            h('el-input', {
              props: {
                value: this.dialogValue,
                placeholder: '请输入关键词',
                clearable: false
              },
              attrs: {
                placeholder: '请输入关键词'
              },
              on: {
                input: this.dialogHandleInput
              },
              nativeOn: {
                keypress: e => {
                  e.stopPropagation()
                  if (e.keyCode === 13) {
                    this.dialoghHandleClickSearch()
                  }
                }
              }
            }, [h('span', { slot: 'append', on: { click: this.dialoghHandleClickSearch }}, '搜索')])
          ])
        ])
        // more
        const more = h('el-button', {
          class: {
            'common-dialog-more': true
          },
          props: {
            type: 'text',
            disabled: this.total <= this.tableData.length || (this.tableData.length > 0 && this.total <= 0)
          },
          on: {
            click: this.getMore
          }
        }, ['加载更多数据', h('i', { class: 'el-icon-arrow-down' })])
        // 已选择table
        // table
        const selectedColumn = [...columns]
        selectedColumn.splice(0, 1, h('el-table-column', {
          props: {
            width: 60,
            align: 'center'
          },
          scopedSlots: {
            header: ({ column, $index }) => {
              return h('span', {
                class: 'common-search-clear-selected',
                on: {
                  click: this.handleClearSelected
                }
              }, '清空')
            },
            default: ({ row, column, $index }) => {
              return h('i', { class: {
                'el-icon-error': true,
                'common-search-cancel-selected': true
              }, on: {
                click: e => this.handleCancelSelected(e, row)
              }})
            }
          }
        }))
        const selectedTable = h('el-table', {
          props: {
            data: this.selectionRows,
            height: 300,
            headerRowClassName: 'table-list-header',
            border: true
          },
          on: {
          }
        }, selectedColumn)
        // tab
        const tabPane = [
          h('el-tab-pane', {
            props: {
              name: 'all',
              label: '全部'
            }
          }, [table, more])
        ]
        if (this.multiple) {
          tabPane.push(h('el-tab-pane', {
            props: {
              name: 'selected',
              label: `已选择(${this.selectionRows.length})`
            }
          }, [selectedTable]))
        }

        // tabs
        const tabs = h('el-tabs', {
          props: {
            value: this.activeTab
          }
        }, tabPane)
        // 确认
        const btns = [
          h('el-button', {
            props: {
              type: 'default'
            },
            on: {
              click: this.handleCancel
            }
          }, '取消'),
          h('el-button', {
            props: {
              type: 'primary'
            },
            on: {
              click: this.handleConfirm
            }
          }, '确定')
        ]
        // dialog
        const dialog = h('el-dialog', {
          props: {
            visible: this.visible,
            title: this.title,
            appendToBody: true,
            lockScroll: true,
            closeOnClickModal: false,
            showClose: false,
            width: this.dialogWidth
          },
          on: {
            'update:visible': v => {
              this.visible = v
            },
            open: this.handleOpen,
            opened: this.handleOpened,
            closed: this.handleClosed
          }
        }, [tabs, title, h('div', { slot: 'footer' }, btns)])
        return dialog
      }

    },
    render(h) {
      if (this.$scopedSlots.default instanceof Function) {
        return h('div', {
          class: {
            'c-search-select-page': true
          }
        }, this.$scopedSlots.default(this.optionsData))
      }
      const vnode = [this.createSselectSearch(h)]
      if (this.showDialog) {
        vnode.push(this.createDialog(h))
      }
      // root
      const root = h('div', {
        class: {
          'c-search-select-page': true
        }
      }, vnode)
      return root
    }
  }
}

